#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <UIKit/UIApplication.h>
#import <LockInfo/Plugin.h>

#import "framework/FWCommon.h"
#import "framework/FWDBAccess.h"
#import "framework/FWApplication.h"
#import "framework/FWApplicationDelegate.h"
#import "framework/FWPreferences.h"
#import "framework/FWListView.h"
#import "framework/FWDetailListView.h"
#import "framework/FWApplication.h"

#import "PIIntegration.h"
#import "PIEventIntegration.h"
#import "PIEventNative.h"
#import "PIEvent.h"
#import "PIAlarm.h"

#import "PICommon.h"
#import "PIEventListAccess.h"
#import "PIEventPlugin.h"
#import "PIEventView.h"
#import "PIEventPreview.h"
#import "PIEventStatus.h"


@implementation PIEventListAccessRange

@synthesize start, duration, color;


+ (PIEventListAccessRange*)accessRangeWithStart:(NSInteger)start duration:(NSInteger)duration color:(UIColor *)color
{
    PIEventListAccessRange* item = [[[PIEventListAccessRange alloc] init] autorelease];
    
    item.start = start;
    item.duration = duration;
    item.color = color;
    
    return item;
}

+ (PIEventListAccessRange*)allDayAccessRange:(UIColor *)color
{
    return [PIEventListAccessRange accessRangeWithStart:0 duration:-1 color:color];
}

- (BOOL)isAllDay
{
    return duration < 0;
}

@end


@implementation PIEventListAccess

@synthesize additionalAlarms;


// ******************************************************************************************
#pragma mark -
#pragma mark Initialisation and object management

- (id)init
{
    if ((self = [super init])) {
    }
    
    return self;
}

- (void)dealloc
{
    [additionalAlarms release];
    
    [super dealloc];
}


// ******************************************************************************************
#pragma mark -
#pragma mark Handling Test events

#ifdef DEVELOPMENT_MODE

- (NSArray*)application:(FWApplication*)application fetchTestDataForPrefs:(FWPreferences*)prefs fromDate:(NSDate*)startDate toDate:(NSDate*)endDate
{
    
    // Single item today from 10:00 - 11:30
    PIEvent* test1 = [PIEvent nativeEventWithKey:@"test1"
                                         version:[[NSDate date] timeIntervalSinceReferenceDate]
                                           title:@"Single item today from 10:00-11:30"
                                            icon:nil
                                        location:@"Test 1 location"
                                       startDate:[NSDate dateTodayAtHour:10 minute:0 section:0]
                               startDateTimeZone:[NSTimeZone systemTimeZone]
                                    startDateRaw:0
                                         endDate:[NSDate dateTodayAtHour:11 minute:30 section:0]
                                 endDateTimeZone:[NSTimeZone systemTimeZone]
                                      endDateRaw:0
                                          allDay:NO
                                        calendar:@"Test 1 calendar"
                                    calendarIcon:nil 
                                   calendarColor:[UIColor redColor]];
    
    // Single item now with alarm 5 mins before
    PIEvent* test3 = [PIEvent nativeEventWithKey:@"test3"
                                         version:[[NSDate date] timeIntervalSinceReferenceDate]
                                           title:@"Single item now with alarm -5"
                                            icon:@"<icon>"
                                        location:nil //@"Test 3 location"
                                       startDate:[NSDate date]
                               startDateTimeZone:[NSTimeZone systemTimeZone]
                                    startDateRaw:0
                                         endDate:[NSDate dateWithTimeIntervalSinceNow:60 * 60]
                                 endDateTimeZone:[NSTimeZone systemTimeZone]
                                      endDateRaw:0
                                          allDay:NO
                                        calendar:@"Test 3 calendar"
                                    calendarIcon:@"<cal-icon>"
                                   calendarColor:[UIColor redColor]];
    
    
    // Single item today in 10 mins with alarm in 2 mins
    PIEvent* test2 = [PIEvent nativeEventWithKey:@"test2"
                                         version:[[NSDate date] timeIntervalSinceReferenceDate]
                                           title:@"Single item today +10 mins with alarm +2"
                                            icon:nil
                                        location:@"Test 2 location with a phone number 0800 123 456 please call"
                                       startDate:[NSDate dateWithTimeIntervalSinceNow:2 * 60]
                               startDateTimeZone:[NSTimeZone systemTimeZone]
                                    startDateRaw:0
                                         endDate:[NSDate dateWithTimeIntervalSinceNow:20 * 60]
                                 endDateTimeZone:[NSTimeZone systemTimeZone]
                                      endDateRaw:0
                                          allDay:NO
                                        calendar:@"Test 2 calendar"
                                    calendarIcon:nil
                                   calendarColor:[UIColor redColor]];
    test2.firstAlarm = test2.nextAlarm = [NSDate dateWithTimeIntervalSinceNow:2 * 60];
    
    // Single item tomorrow now
    PIEvent* test4 = [PIEvent nativeEventWithKey:@"test4"
                                         version:[[NSDate date] timeIntervalSinceReferenceDate]
                                           title:@"Single item tomorrow"
                                            icon:nil
                                        location:@"Test 4 location"
                                       startDate:[NSDate dateWithTimeIntervalSinceNow:SECONDS_PER_DAY]
                               startDateTimeZone:[NSTimeZone systemTimeZone]
                                    startDateRaw:0
                                         endDate:[NSDate dateWithTimeIntervalSinceNow:SECONDS_PER_DAY + 20 * 60]
                                 endDateTimeZone:[NSTimeZone systemTimeZone]
                                      endDateRaw:0
                                          allDay:NO
                                        calendar:@"Test 4 calendar"
                                    calendarIcon:nil
                                   calendarColor:[UIColor redColor]];
    test4.invitation = YES;
    
    // All day today
    PIEvent* test5 = [PIEvent nativeEventWithKey:@"test5"
                                         version:[[NSDate date] timeIntervalSinceReferenceDate]
                                           title:@"All day today"
                                            icon:nil
                                        location:@"Barnsley UK"
                                       startDate:[NSDate dateTodayAtHour:0 minute:0 section:0]
                               startDateTimeZone:[NSTimeZone systemTimeZone]
                                    startDateRaw:0
                                         endDate:[NSDate dateTodayAtHour:23 minute:59 section:59]
                                 endDateTimeZone:[NSTimeZone systemTimeZone]
                                      endDateRaw:0
                                          allDay:YES
                                        calendar:@"Test 5 calendar"
                                    calendarIcon:nil
                                   calendarColor:[UIColor blueColor]];
    
    PIEvent* test6 = [PIEvent nativeEventWithKey:@"test6"
                                         version:[[NSDate date] timeIntervalSinceReferenceDate]
                                           title:@"All day today with a long title"
                                            icon:nil
                                        location:nil
                                       startDate:[NSDate dateTodayAtHour:0 minute:0 section:0]
                               startDateTimeZone:[NSTimeZone systemTimeZone]
                                    startDateRaw:0
                                         endDate:[NSDate dateTodayAtHour:23 minute:59 section:59]
                                 endDateTimeZone:[NSTimeZone systemTimeZone]
                                      endDateRaw:0
                                          allDay:YES
                                        calendar:@"Test 6 calendar"
                                    calendarIcon:nil
                                   calendarColor:[UIColor yellowColor]];
    
    PIEvent* test7 = [PIEvent nativeEventWithKey:@"test7"
                                         version:[[NSDate date] timeIntervalSinceReferenceDate]
                                           title:@"All day today"
                                            icon:nil
                                        location:@"Test 7 location"
                                       startDate:[[NSDate dateTodayAtHour:0 minute:0 section:0] dateByAddingTimeInterval:SECONDS_PER_DAY * 4]
                               startDateTimeZone:[NSTimeZone systemTimeZone]
                                    startDateRaw:0
                                         endDate:[[NSDate dateTodayAtHour:23 minute:59 section:59] dateByAddingTimeInterval:SECONDS_PER_DAY * 4]
                                 endDateTimeZone:[NSTimeZone systemTimeZone]
                                      endDateRaw:0
                                          allDay:YES
                                        calendar:@"Test 7 calendar"
                                    calendarIcon:nil
                                   calendarColor:[UIColor greenColor]];
    
    PIEvent* test8 = [PIEvent nativeEventWithKey:@"test8"
                                         version:[[NSDate date] timeIntervalSinceReferenceDate]
                                           title:@"All day 3 days"
                                            icon:nil
                                        location:@"Test 8 location"
                                       startDate:[NSDate dateTodayAtHour:0 minute:0 section:0]
                               startDateTimeZone:[NSTimeZone systemTimeZone]
                                    startDateRaw:0
                                         endDate:[[NSDate dateTodayAtHour:23 minute:59 section:59] dateByAddingTimeInterval:SECONDS_PER_DAY * 3]
                                 endDateTimeZone:[NSTimeZone systemTimeZone]
                                      endDateRaw:0
                                          allDay:YES
                                        calendar:@"Test 8 calendar"
                                    calendarIcon:nil
                                   calendarColor:[UIColor greenColor]];
    
    PIEvent* test9 = [PIEvent nativeEventWithKey:@"test9"
                                         version:[[NSDate date] timeIntervalSinceReferenceDate]
                                           title:@"Today 4 hours ago"
                                            icon:nil
                                        location:@"Test 9 location"
                                       startDate:[NSDate dateWithTimeIntervalSinceNow:-4 * SECONDS_IN_HOUR]
                               startDateTimeZone:[NSTimeZone systemTimeZone]
                                    startDateRaw:0
                                         endDate:[NSDate dateWithTimeIntervalSinceNow:-3 * SECONDS_IN_HOUR]
                                 endDateTimeZone:[NSTimeZone systemTimeZone]
                                      endDateRaw:0
                                          allDay:NO
                                        calendar:@"Test 9 calendar"
                                    calendarIcon:nil
                                   calendarColor:[UIColor purpleColor]];
    
    PIEvent* test10 = [PIEvent nativeEventWithKey:@"test10"
                                          version:[[NSDate date] timeIntervalSinceReferenceDate]
                                            title:@"Today 30 mins ago"
                                             icon:nil
                                         location:@"Test 10 location"
                                        startDate:[NSDate dateWithTimeIntervalSinceNow:-30 * SECONDS_IN_MINUTE]
                                startDateTimeZone:[NSTimeZone timeZoneWithName:@"PST"]
                                     startDateRaw:0
                                          endDate:[NSDate dateWithTimeIntervalSinceNow:-15 * SECONDS_IN_MINUTE]
                                  endDateTimeZone:[NSTimeZone timeZoneWithName:@"EST"]
                                       endDateRaw:0
                                           allDay:NO
                                         calendar:@"Test 10 calendar"
                                     calendarIcon:nil
                                    calendarColor:[UIColor lightGrayColor]];

    return [NSArray arrayWithObjects:
            test1,
            test2,
            //test3,
            test4,
            test5,
            test6,
            test7,
            test8,
            test9,
            test10,
            nil];
    //     
    //     [NSMutableDictionary dictionaryWithObjectsAndKeys:
    //                      NSNumberYES, kPIEventListAccessFieldIsTest,
    //                      
    //                      @"Single item now with alarm -5", kPIEventListAccessFieldTitle,
    //                      
    //                      @"test3", kPIEventListAccessFieldKey,
    //                      [NSDate date] , kPIEventListAccessFieldStart,
    //                      [NSDate dateWithTimeIntervalSinceNow:60 * 60], kPIEventListAccessFieldEnd,
    //                      @"Test 3 location", kPIEventListAccessFieldLocation,
    //                      
    //                      @"Test 3 calendar", kPIEventListAccessFieldCalendar,
    //                      [UIColor redColor], kPIEventListAccessFieldColor,
    //                      
    //                      NSNumberNO, kPIEventListAccessFieldIsAllDay,
    //                      NSNumberNO, kPIEventListAccessFieldHasAttendees,
    //                      NSNumberYES, kPIEventListAccessFieldHasReminder,
    //                      NSNumberNO, kPIEventListAccessFieldIsRepeating,
    //                      
    //                      [NSDate dateWithTimeIntervalSinceNow:-5 * 60], kPIEventListAccessFieldFirstAlarm,
    //                      [NSDate dateWithTimeIntervalSinceNow:-5 * 60], kPIEventListAccessFieldNextAlarm,
    //                      
    //                      NSNumberNO, kPIEventListAccessFieldIsPI,
    //                      NSNumberYES, kPIEventListAccessFieldHasDetails,
    //                      [NSNumber numberWithInt:kPIEventAvailabilityNotSupported], kPIEventListAccessFieldAvailability,
    //                      nil]];
    //
    //    // Single item today in 10 mins with alarm in 2 mins
    //    [tests addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
    //                      NSNumberYES, kPIEventListAccessFieldIsTest,
    //                      
    //                      @"Single item today +10 mins with alarm +2", kPIEventListAccessFieldTitle,
    //                      
    //                      @"test2", kPIEventListAccessFieldKey,
    //                      [NSDate dateWithTimeIntervalSinceNow:2*60] , kPIEventListAccessFieldStart,
    //                      [NSDate dateWithTimeIntervalSinceNow:20*60], kPIEventListAccessFieldEnd,
    //                      @"Test 2 location", kPIEventListAccessFieldLocation,
    //                      
    //                      @"Test 2 calendar", kPIEventListAccessFieldCalendar,
    //                      [UIColor redColor], kPIEventListAccessFieldColor,
    //
    //                      NSNumberNO, kPIEventListAccessFieldIsAllDay,
    //                      NSNumberNO, kPIEventListAccessFieldHasAttendees,
    //                      NSNumberYES, kPIEventListAccessFieldHasReminder,
    //                      NSNumberNO, kPIEventListAccessFieldIsRepeating,
    //                      
    //                      [NSDate dateWithTimeIntervalSinceNow:2 * 60], kPIEventListAccessFieldFirstAlarm,
    //                      [NSDate dateWithTimeIntervalSinceNow:2 * 60], kPIEventListAccessFieldNextAlarm,
    //                      
    //                      NSNumberNO, kPIEventListAccessFieldIsPI,
    //                      NSNumberYES, kPIEventListAccessFieldHasDetails,
    //                      [NSNumber numberWithInt:kPIEventAvailabilityNotSupported], kPIEventListAccessFieldAvailability,
    //                      nil]];
    //
    //    // Single item tomorrow now
    //    [tests addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
    //                      NSNumberYES, kPIEventListAccessFieldIsTest,
    //                      
    //                      @"Single item tomorrow", kPIEventListAccessFieldTitle,
    //                      
    //                      @"test4", kPIEventListAccessFieldKey,
    //                      [NSDate dateWithTimeIntervalSinceNow:SECONDS_PER_DAY] , kPIEventListAccessFieldStart,
    //                      [NSDate dateWithTimeIntervalSinceNow:SECONDS_PER_DAY + 20*60], kPIEventListAccessFieldEnd,
    //                      @"Test 4 location", kPIEventListAccessFieldLocation,
    //                      
    //                      @"Test 4 calendar", kPIEventListAccessFieldCalendar,
    //                      [UIColor redColor], kPIEventListAccessFieldColor,
    //                      
    //                      NSNumberNO, kPIEventListAccessFieldIsAllDay,
    //                      NSNumberNO, kPIEventListAccessFieldHasAttendees,
    //                      NSNumberYES, kPIEventListAccessFieldHasReminder,
    //                      NSNumberNO, kPIEventListAccessFieldIsRepeating,
    //                      
    //                      NSNumberNO, kPIEventListAccessFieldIsPI,
    //                      NSNumberYES, kPIEventListAccessFieldHasDetails,
    //                      [NSNumber numberWithInt:kPIEventAvailabilityNotSupported], kPIEventListAccessFieldAvailability,
    //                      nil]];
    //
    //    // All day tomorrow
    //    [tests addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
    //                      NSNumberYES, kPIEventListAccessFieldIsTest,
    //                      
    //                      @"All day tomorrow", kPIEventListAccessFieldTitle,
    //                      
    //                      @"test5", kPIEventListAccessFieldKey,
    //                      [NSDate dateWithTimeIntervalSinceNow:SECONDS_PER_DAY] , kPIEventListAccessFieldStart,
    //                      [NSDate dateWithTimeIntervalSinceNow:SECONDS_PER_DAY + 20*60], kPIEventListAccessFieldEnd,
    //                      @"Test 5 location", kPIEventListAccessFieldLocation,
    //                      
    //                      @"Test 5 calendar", kPIEventListAccessFieldCalendar,
    //                      [UIColor blueColor], kPIEventListAccessFieldColor,
    //                      
    //                      NSNumberYES, kPIEventListAccessFieldIsAllDay,
    //                      NSNumberNO, kPIEventListAccessFieldHasAttendees,
    //                      NSNumberYES, kPIEventListAccessFieldHasReminder,
    //                      NSNumberNO, kPIEventListAccessFieldIsRepeating,
    //                      
    //                      NSNumberNO, kPIEventListAccessFieldIsPI,
    //                      NSNumberYES, kPIEventListAccessFieldHasDetails,
    //                      [NSNumber numberWithInt:kPIEventAvailabilityNotSupported], kPIEventListAccessFieldAvailability,
    //                      nil]];
    //    [tests addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
    //                      NSNumberYES, kPIEventListAccessFieldIsTest,
    //                      
    //                      @"All day tomorrow", kPIEventListAccessFieldTitle,
    //                      
    //                      @"test6", kPIEventListAccessFieldKey,
    //                      [NSDate dateWithTimeIntervalSinceNow:SECONDS_PER_DAY] , kPIEventListAccessFieldStart,
    //                      [NSDate dateWithTimeIntervalSinceNow:SECONDS_PER_DAY + 20*60], kPIEventListAccessFieldEnd,
    //                      @"Test 6 location", kPIEventListAccessFieldLocation,
    //                      
    //                      @"Test 6 calendar", kPIEventListAccessFieldCalendar,
    //                      [UIColor yellowColor], kPIEventListAccessFieldColor,
    //                      
    //                      NSNumberYES, kPIEventListAccessFieldIsAllDay,
    //                      NSNumberNO, kPIEventListAccessFieldHasAttendees,
    //                      NSNumberYES, kPIEventListAccessFieldHasReminder,
    //                      NSNumberNO, kPIEventListAccessFieldIsRepeating,
    //                      
    //                      NSNumberNO, kPIEventListAccessFieldIsPI,
    //                      NSNumberYES, kPIEventListAccessFieldHasDetails,
    //                      [NSNumber numberWithInt:kPIEventAvailabilityNotSupported], kPIEventListAccessFieldAvailability,
    //                      nil]];
    //    [tests addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
    //                      NSNumberYES, kPIEventListAccessFieldIsTest,
    //                      
    //                      @"All day tomorrow", kPIEventListAccessFieldTitle,
    //                      
    //                      @"test7", kPIEventListAccessFieldKey,
    //                      [NSDate dateWithTimeIntervalSinceNow:SECONDS_PER_DAY] , kPIEventListAccessFieldStart,
    //                      [NSDate dateWithTimeIntervalSinceNow:SECONDS_PER_DAY + 20*60], kPIEventListAccessFieldEnd,
    //                      @"Test 7 location", kPIEventListAccessFieldLocation,
    //                      
    //                      @"Test 7 calendar", kPIEventListAccessFieldCalendar,
    //                      [UIColor orangeColor], kPIEventListAccessFieldColor,
    //                      
    //                      NSNumberYES, kPIEventListAccessFieldIsAllDay,
    //                      NSNumberNO, kPIEventListAccessFieldHasAttendees,
    //                      NSNumberYES, kPIEventListAccessFieldHasReminder,
    //                      NSNumberNO, kPIEventListAccessFieldIsRepeating,
    //                      
    //                      NSNumberNO, kPIEventListAccessFieldIsPI,
    //                      NSNumberYES, kPIEventListAccessFieldHasDetails,
    //                      [NSNumber numberWithInt:kPIEventAvailabilityNotSupported], kPIEventListAccessFieldAvailability,
    //                      nil]];
    //
    //    return tests;
}

#endif


// ******************************************************************************************
#pragma mark -
#pragma mark Handling event list

- (NSMutableArray*)mutableAdditionalAlarmsList
{
    NSMutableArray* result = [NSMutableArray arrayWithCapacity:additionalAlarms ? additionalAlarms.count : 0];
    
    if (additionalAlarms) {
        NSDate* now = [NSDate date];
        
        for (PIAlarm* alarm in additionalAlarms) {
            // If date of the entry is not before current date then keep in the list
            if ([alarm.date isEqualOrLaterThanDate:now])
                [result addObject:alarm];
            else
                XLog(@"LI:PIEvent: Expired extra alarm %@", alarm);
        }
    }
    
    return result;
}

NSInteger compareEvents(id num1, id num2, void *context)
{
    NSComparisonResult result = [((PIEvent*)num1).startDate compare:((PIEvent*)num2).startDate];
    if (result != NSOrderedSame)
        return result;
    else
        return [((PIEvent*)num1).calendar compare:((PIEvent*)num2).calendar];
}

- (NSArray*)fetchNewDataForPrefs:(FWPreferences*)prefs application:(FWApplication*)application 
{
    XLog(@"LI:PIEvent: Updating calendar...");
    
    NSBundle* bundle = [NSBundle bundleForClass:[self class]];
    PIEventPlugin* plugin = (PIEventPlugin*)application.fwPlugin;
    PIEventStatus* status = (PIEventStatus*)application.info;
    
    // Remove error messages from screen
    [application.fwPlugin resetMessageBox];

    // Read current display settings
    plugin.debugMode = [prefs intValue:kPIOptionsDebugCode withDefault:kPIOptionsDebugCodeDefault] == kDebugModeCode;
    status.viewStyle = (kPIEventViewStyle)[prefs intValue:kPIEventOptionsViewStyle withDefault:kPIEventOptionsViewStyleDefault];
    status.showCalendar = [prefs boolValue:kPIEventOptionsShowCalendar withDefault:kPIEventOptionsShowCalendarDefault];
    status.shortDates = [prefs intValue:kPIOptionsShortDates withDefault:kPIOptionsShortDatesDefault];
    status.showIcons = [prefs boolValue:kPIOptionsShowIcons withDefault:kPIOptionsShowIconsDefault];
    status.singleLineOniPad = [prefs boolValue:kPIOptionsiPadSingleLine withDefault:kPIOptionsiPadSingleLineDefault];
    status.showAvailability = [prefs boolValue:kPIEventOptionsShowAvailability withDefault:kPIEventOptionsShowAvailabilityDefault]; 
    status.showEmoji = [prefs boolValue:kPIOptionsShowEmoji withDefault:kPIOptionsShowEmojiDefault]; 
    status.emojiAfter = [prefs boolValue:kPIOptionsEmojiAfter withDefault:kPIOptionsEmojiAfterDefault]; 
    status.lowColour = [prefs boolValue:kPIOptionsLowColourDisplay withDefault:kPIOptionsLowColourDisplayDefault];
    status.showListDetails = [prefs intValue:kPIOptionsShowDates withDefault:kPIOptionsShowDatesDefault];
    status.showAvailability = [prefs boolValue:kPIEventOptionsShowAvailability withDefault:kPIEventOptionsShowAvailabilityDefault];
    status.showSourceIcons = [prefs intValue:kPIOptionsShowSourceIcons withDefault:kPIOptionsShowSourceIconsDefault];
    
    plugin.eventStoreUpdated = NO;    // Mark as no longer updated

    BOOL debug = plugin.isDebugMode;
    
    NSInteger days = [prefs intValue:kPIOptionsDayLimit withDefault:kPIOptionsDayLimitDefault];
    NSInteger weeks = ceil(days / 7.0);
    
    // If skipping weekends then extend the number of days we search
    BOOL skipWeekends = [prefs boolValue:kPIOptionsSkipWeekend withDefault:kPIOptionsSkipWeekendDefault];
    FWWeekdayName weekendStart = (FWWeekdayName)[prefs intValue:kPIOptionsWeekendStart withDefault:kPIOptionsWeekendStartDefault];
    if (weekendStart == FWWeekdayNameUnknown)
        skipWeekends = NO;
    if (skipWeekends)
        days += weeks * 2;

    int maxItems = [prefs intValue:kPIOptionsMaxEvents withDefault:kPIOptionsMaxEventsDefault];
    int maxDays = [prefs intValue:kPIOptionsMaxDays withDefault:kPIOptionsMaxDaysDefault];
    BOOL futureEventsOnly = [prefs boolValue:kPIEventOptionsFutureOnly withDefault:kPIEventOptionsFutureOnlyDefault];
    BOOL pastEvents = [prefs boolValue:kPIEventOptionsShowPastEvents withDefault:kPIEventOptionsShowPastEventsDefault];
    
    // Search forward enough days for the next working day
    if (maxDays == -2)
        days = days > 5 ? days : 5;
    else if (maxDays == -1)
        days = days > 4 ? days : 4;
    
    NSDate* midnight = FWLocalDateForLocalMidnight();
    NSDate* todayWorkEnd = [midnight addTimeInterval:[prefs intValue:kPIOptionsDayEnd withDefault:kPIOptionsDayEndDefault]];
    NSDate* endDate = [midnight addTimeInterval:SECONDS_PER_DAY * days];
    NSDate* startDate = [midnight addTimeInterval:-SECONDS_PER_DAY];
    NSDate* now = [NSDate date];
    
    NSDate* lastListRefresh = status.lastListRefresh;
    status.lastListRefresh = now;
    
#ifdef DEVELOPMENT_MODE
    //    startDate = [midnight addTimeInterval:-SECONDS_PER_DAY * 30];
    //    now = startDate;
    //    midnight = startDate;
#endif
    
    FWDatabase* database = nil;
    @try {
        // Get a single database connection
        if (plugin.isPocketInformantPresent && !plugin.isNativeOnly)
            database = FWDBConnectDatabase(application.databasePath, application);
        
        XLog(@"LI:PIEvent: Rebuilding list of events for %d days; weeks = %d; start = %@; end = %@.", days, weeks, startDate, endDate);
        if (debug) {
            XLog(@"LI:PIEvent: Now = %@; Midnight = %@", now, midnight);
        }

        NSArray* iosEvents = [PIEventNative basicEventsList:application prefs:prefs database:database fromDate:startDate toDate:endDate];
        if (debug)
            XLog(@"LI:PIEvent: %i events from iOS calendar", iosEvents.count);
        
        NSArray* piEvents = [PIEventIntegration basicEventsList:application prefs:prefs database:database fromDate:startDate toDate:endDate];
        if (debug)
            XLog(@"LI:PIEvent: %i events from PI calendar", piEvents.count);
        
        NSMutableArray* rawList = [NSMutableArray arrayWithArray:iosEvents];
        [rawList addObjectsFromArray:piEvents];
        
#ifdef DEVELOPMENT_MODE
        [rawList addObjectsFromArray:[self application:application fetchTestDataForPrefs:prefs fromDate:startDate toDate:endDate]];
#endif    
        
        XLog(@"LI:PIEvent: %i events in initial combined list", rawList.count);
        
        // Search for entries that span a day. for each create additional entries for the extra days
        NSMutableArray* extras = [NSMutableArray arrayWithCapacity:10];
        // Deliberate crash - working on decoding crash reports
        //    [extras insertObject:@"hello" atIndex:2];
        
        NSCalendar* cal = [NSCalendar autoupdatingCurrentCalendar];
        cal.timeZone = [NSTimeZone systemTimeZone];
        
        int mask = (NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit);
        for (PIEvent* event in rawList) {
            NSDate* start = event.startDate;
            NSDate* end = event.endDate;
            
            // If event spans days then add duplicate entries
            if (!FWIsLocalDateSameDay(start, end)) {
                NSDateComponents* comps = [cal components:mask fromDate:start];
                
                [comps setHour:0];
                [comps setMinute:0];
                [comps setSecond:0];
                NSDate* nextStart = [cal dateFromComponents:comps];
                
                [comps setHour:23];
                [comps setMinute:59];
                [comps setSecond:59];
                NSDate* nextEnd = [cal dateFromComponents:comps];
                NSDate* endFor1stItem = nextEnd;
                
                // Record the original start and end periods
                event.rangeStartDate = start;
                event.rangeEndDate = end;
                NSInteger instance = 0;
                
                do {
                    nextStart = [nextStart addTimeInterval:SECONDS_PER_DAY];
                    nextEnd = [nextEnd addTimeInterval:SECONDS_PER_DAY];
                    
                    PIEvent* newItem = [event copyInstance:++instance];
                    newItem.startDate = nextStart;
                    
                    // Remove items that the replicants shouldn't respond to
                    newItem.firstAlarm = [NSDate nullDate];
                    
                    // if not finishing today then set end time at midnight
                    //if ([nextEnd compare:end] == NSOrderedAscending) {
                    if ([nextEnd isEarlierThanDate:end]) {
                        newItem.endDate = nextEnd;
                        newItem.allDay = YES;
                    }
                    
                    // If the start of this item and the end of the sequence are the same
                    // then this is likely a repeat of an item that was really a 00:00-00:00 all-day
                    // item so we don't want the replicant
                    if ([nextStart isEqualToDate:end])
                        break;
                    
                    [extras addObject:newItem];
                }
                //while (([end compare:nextEnd] == NSOrderedDescending) && ([endDate compare:nextEnd] == NSOrderedDescending));
                while ([end isLaterThanDate:nextEnd] && [endDate isLaterThanDate:nextEnd]);
                
                // Overwrite the end date of the original item
                event.endDate = endFor1stItem;
            }
        }
        [rawList addObjectsFromArray:extras];
        
        XLog(@"LI:PIEvent: %i events in expanded repeating elements list", rawList.count);
        
        // Sort events into ascending order
        if ([rawList count] > 0) {
            [rawList sortUsingFunction:compareEvents context:nil];
            if (debug)
                XLog(@"LI:PIEvent: Sorted event list before filtering: %@", rawList);
        }
        
        // Find the first event on each day and mark it as a section header
        NSDate* lastDate = nil;
        NSDate* nextChangeDue = nil;
        NSMutableArray* filteredList = [NSMutableArray arrayWithCapacity:[rawList count]];
        
        BOOL showWorkingHours = [prefs boolValue:kPIOptionsShowWorkingHours withDefault:kPIOptionsShowWorkingHoursDefault];
        NSInteger dayStart = [prefs intValue:kPIOptionsDayStart withDefault:kPIOptionsDayStartDefault];
        NSInteger dayEnd = [prefs intValue:kPIOptionsDayEnd withDefault:kPIOptionsDayEndDefault];
        if (!showWorkingHours) {
            dayStart = 0;
            dayEnd = SECONDS_PER_DAY;
        }
        
        kPIEventDaySummaryStyle summaryStyle = (kPIEventDaySummaryStyle)[prefs intValue:kPIEventOptionsDaySummary
                                                                            withDefault:kPIEventOptionsDaySummaryDefault];
        
        // Update (and expire any old entries) the list of extra alarms
        NSMutableArray* extraAlarms = [self mutableAdditionalAlarmsList];
        self.additionalAlarms = extraAlarms;
        NSMutableArray* daySummarySections = [NSMutableArray arrayWithCapacity:5];
        BOOL workdaySeen = NO;

        if (debug)
            XLog(@"LI:PIEvent: Processing raw event list for %d days...", maxDays);

        for (PIEvent* event in rawList) {
            // Search for time of next event start or end after the current date. We will
            // need to update then
            NSDate* start = event.startDate;
            NSDate* end = event.endDate;
            
            if (!nextChangeDue || [start isEarlierThanDate:nextChangeDue]) {
                // Set next update if start is in the future
                if ([start isLaterThanDate:now])
                    nextChangeDue = start;
            }
            if (!nextChangeDue || [end isEarlierThanDate:nextChangeDue]) {
                // Set next update if end is in the future
                if (!event.isAllDay && [end isLaterThanDate:now])
                    nextChangeDue = end;
            }
            
            // Have we gone past our end date?
            if ([start isLaterThanDate:endDate]) {
                if (debug)
                    XLog(@"LI:PIEvent: Event after end date %@ - dropping all further: %@", endDate, event.shortDescription);
                break;
            }
            
            // Are we before today?
            if ([start isEarlierThanDate:midnight]) {
                if (debug)
                    XLog(@"LI:PIEvent: Event before start of day %@ - ignoring: %@", midnight, event.shortDescription);
                continue;
            }
            
            // Skip over the weekend if selected
            FWWeekdayName weekday = FWLocalWeekdayName(start);
            if (skipWeekends) {
                if (FWIsDayWeekend(weekday, weekendStart)) {
                    if (debug)
                        XLog(@"LI:PIEvent: Event is weekend item - ignoring: %@", event.shortDescription);
                    continue;
                }
            }

            // Have we seen a workday?
            if (!workdaySeen) {
                workdaySeen = !FWIsDayWeekend(weekday, weekendStart);
                if (workdaySeen) {
                    if (FWIsLocalDateSameDay(start, todayWorkEnd) && [now isEqualOrLaterThanDate:todayWorkEnd])
                        workdaySeen = NO;
                    
                    if (workdaySeen) {
                        if (maxDays == -2)
                            maxDays = -1;
                        else if (maxDays < 0)
                            maxDays = 1;
                        if (debug)
                            XLog(@"LI:PIEvent: Detected new working day: start = %@", start);
                    }
                }
            }
                
            // Only add items if after the current date
            if (event.isAllDay ||
                pastEvents ||
                [start isLaterThanDate:now] ||
                ([start isEqualOrEarlierThanDate:now] && [end isLaterThanDate:now] && !futureEventsOnly)) {
                
                // If current date not the same day as the last event then we need a new
                // section header
                if (!lastDate || !FWIsLocalDateSameDay(lastDate, start)) {
                    if (debug)
                        XLog(@"LI:PIEvent: Starting new day record: %@", event.shortDescription);
                    
                    // Have we recorded enough days?
                    if ((maxDays >= 0) && (--maxDays < 0)) {
                        if (debug)
                            XLog(@"LI:PIEvent: Have processed enough days - dropping remainder: %@", event.shortDescription);
                        break;
                    }

                    event.sectionTitle = FWLocalDateStringForUTCDate(start, FWDateFormatterLongFormat, NO, bundle);
                    if (summaryStyle != kPIEventDaySummaryStyleNone) {
                        // If we have already shown a date then we haven't got any past items to store so
                        // start a new list
                        if (lastDate)
                            daySummarySections = [NSMutableArray arrayWithCapacity:5];
                        
                        event.sectionDetails = daySummarySections;
                        event.sectionStartInterval = dayStart;
                        event.sectionEndInterval = dayEnd;
                        event.summaryDisplay = YES;
                        event.updateRequired = YES;
                        
                        // If we have seen a workday but not yet seen enough workdays then reset the flag
                        if (workdaySeen && (maxDays < 0))
                            workdaySeen = NO;
                    }
                }

 
                if (event.isAllDay ||
                    pastEvents ||
                    [start isLaterThanDate:now] ||
                    ([start isEqualOrEarlierThanDate:now] && [end isLaterThanDate:now] && !futureEventsOnly)) {
                    
                    if (debug)
                        XLog(@"LI:PIEvent: Added to event list: %@", event.shortDescription);
                    [filteredList addObject:event];
                    
                    // If the item may have ended since the last refresh then make sure it is updated
                    if ([event.endDate isEarlierThanDate:now] && [event.endDate isEqualOrLaterThanDate:lastListRefresh])
                        event.updateRequired = YES;
                    
                    // Have we recorded enough events?
                    --maxItems;
                    
                    // Remember the last date we processed
                    lastDate = start;
                }
            }
            else {
                if (debug)
                    XLog(@"LI:PIEvent: Event outside date range - ignoring: %@", event.shortDescription);
            }

            // Add entry to the summary of time intervals for the day
            if (event.isAllDay) {
                if (summaryStyle == kPIEventDaySummaryStyleFull) {
                    UIColor* color = event.calendarColor;
                    for (PIEventListAccessRange* range in daySummarySections) {
                        if ((range.duration < 0) && (range.color == color)) {
                            color = nil;
                            break;
                        }
                    }
                    if (color)
                        [daySummarySections addObject:[PIEventListAccessRange allDayAccessRange:color]];
                }
            }
            else {
                NSInteger begins = FWSecondsWithinLocalDate(start);
                NSInteger interval = FWSecondsWithinLocalDate(end) - begins;
                
                // If end time is before start then it's the next day
                if (interval < 0)
                    interval = SECONDS_PER_DAY - begins;
                
                if (summaryStyle != kPIEventDaySummaryStyleNone)
                    [daySummarySections addObject:[PIEventListAccessRange accessRangeWithStart:begins
                                                                                      duration:interval
                                                                                         color:event.calendarColor]];
            }
            
            // Have we recorded enough events?
            if (maxItems <= 0) {
                if (debug)
                    XLog(@"LI:PIEvent: List has enough items - dropping remainder");
                break;
            }
        }
        
        [PIEventIntegration addAlarmDataToEventList:application database:database events:filteredList prefs:prefs];

        if (debug)
            XLog(@"LI:PIEvent: Searching for next alarm...");
        
        // Find the next due alarm
        NSDate* nextAlarmDue = nil;
        for (PIEvent* event in filteredList) {
            // If there is an entry for this item in the list of extra alarms and it has an
            // earlier alarm date then we will use it for our next alarm
            NSString* key = event.key;
            NSDate* alarm = event.nextAlarm;
            
            for (PIAlarm* extraAlarm in extraAlarms) {
                if ([key isEqualToString:extraAlarm.key]) {
                    if (extraAlarm.type == kPIEventAlarmTypeAlarmIsActive) {
                        event.reminderInteract = YES;
                        if (debug)
                            XLog(@"LI:PIEvent: Marked alarm active: %@", event.shortDescription);
                    }
                    // If the extra alarm's date is earlier than the current then we want to use it
                    else if ([alarm isNull] || [extraAlarm.date isEarlierThanDate:alarm]) {
                        event.nextAlarm = extraAlarm.date;
                        alarm = extraAlarm.date;
                        
                        if (debug)
                            XLog(@"LI:PIEvent: Set new next alarm %@", extraAlarm);
                    }
                    else {
                        if (debug)
                            XLog(@"LI:PIEvent: Skipped new next alarm at %@, existing %@", extraAlarm, alarm);
                    }
                }
            }

            if (![event.nextAlarm isNull]) {
                if (!nextAlarmDue || [nextAlarmDue isLaterThanDate:event.nextAlarm])
                    nextAlarmDue = event.nextAlarm;
            }
            
#ifdef DEBUG
            //        event.reminderInteract = YES;
#endif
        }
        
        XLog(@"LI:PIEvent: %i events in final list", filteredList.count);
        
        // Wakeup at the earlier of the next midnight or the next event or the next alarm
        NSDate* nextWakeup = [midnight addTimeInterval:SECONDS_PER_DAY];
        if (debug)
            XLog(@"LI:PIEvent: Calculating next wakeup; current = %@", nextWakeup);

        if ([now isEqualOrEarlierThanDate:todayWorkEnd] && [todayWorkEnd isEarlierThanDate:nextWakeup]) {
            if (debug)
                XLog(@"LI:PIEvent: This day end before next wakeup; dayEnd = %@", todayWorkEnd);
            nextWakeup = todayWorkEnd;
        }
        if (nextAlarmDue && [nextAlarmDue isEarlierThanDate:nextWakeup]) {
            if (debug)
                XLog(@"LI:PIEvent: Next alarm due before next wakeup; alarmDue = %@", nextAlarmDue);
            nextWakeup = nextAlarmDue;
        }
        if (nextChangeDue && [nextChangeDue isEarlierThanDate:nextWakeup]) {
            if (debug)
                XLog(@"LI:PIEvent: Next change due before next wakeup; changeDue = %@", nextChangeDue);
            nextWakeup = nextChangeDue;
        }
        
        if ([nextAlarmDue isNull])
            nextAlarmDue = nil;
        if ([nextWakeup isNull])
            nextWakeup = nil;
        
        status.nextAlarmDue = nextAlarmDue;
        status.nextChangeDue = nextWakeup;
        
        XLog(@"LI:PIEvent: Next scheduled update will be at %@", nextWakeup);
        XLog(@"LI:PIEvent: Next scheduled alarm will be at %@", nextAlarmDue);
        
        [plugin notifyNextTimerEventDate:nextWakeup];
        [application.fwPlugin scheduleNextTimerEvent:nextWakeup];
        
        // Use the original data list
        return filteredList;
    }
    @catch (NSException *exception) {
        NSLog(@"LI:%@: Exception; %@", application.resourceName, exception);
        
        [application.fwPlugin setMessageBox:@"Exception while building event list"
                                      line2:exception.name
                                     detail:[NSString stringWithFormat:@"%@\n----------\n%@",
                                             exception.reason,
                                             [exception.callStackSymbols description]]];
        
        return [NSArray array];
    }
    @finally {
        FWDBDisconnectDatabase(database);
    }
    
    // No list returned
    return [NSArray array];
}


// ******************************************************************************************
#pragma mark -
#pragma mark Alarm support

- (BOOL)shouldUpdateForDate:(NSDate *)date application:(FWApplication *)app
{
    PIEventStatus* info = (PIEventStatus*)app.info;
    NSDate* now = [NSDate date];
    
    DebugLog(@"LI:PIEvent: Next scheduled alarm %@, now = %@", info.nextAlarmDue, now);
    if (info.nextAlarmDue && [info.nextAlarmDue isEqualOrEarlierThanDate:now]) {
        // Check for any newly triggered alarms
        [(PIEventPlugin*)app.fwPlugin checkForNewAlarmsForDate:info.nextAlarmDue];
        
        // Update the display
        info.nextAlarmDue = nil;
        return YES;
    }
    
    if (((PIEventPlugin*)app.fwPlugin).isEventStoreUpdated) {
        XLog(@"LI:PIEvent: Event store has been updated");
        return YES;
    }
    else if (info.nextChangeDue && [info.nextChangeDue isEqualOrEarlierThanDate:now]) {
        XLog(@"LI:PIEvent: Next scheduled update is due");
        return YES;
    }
    else {
        DebugLog(@"LI:PIEvent: No update required");
        return NO;
    }
}    


// ******************************************************************************************
#pragma mark -
#pragma mark Describing the layout

- (BOOL)shouldShowDetailLine:(PIEvent*)event application:(FWApplication*)app preferences:(FWPreferences*)prefs forItem:(BOOL)forItem
{
    PIEventStatus* status = (PIEventStatus*)app.info;
    
    // Don't display on the lockscreen
    if (app.isLockScreen && ![FWPreferences boolValue:kPIOptionsLockDetails withDefault:kPIOptionsLockDetailsDefault preferences:app.fwPlugin.liPlugin.preferences])
        return NO;
    
    // Have we been told to override the showing of details?
    NSInteger showDetails = status.showListDetails;
    if (showDetails == ShowDatesNever)
        return NO;
    else if (showDetails == ShowDatesAlways)
        return YES;
    
    if (forItem) {
        if (event.hasDetails)
            return YES;
        //        else if (status.viewStyle == kPIEventViewStyleTraditional)
        //            return status.isShowCalendar;
        else
            return status.isShowCalendar;
    }
    else
        return NO;
}

- (CGFloat)heightForItem:(NSObject *)item theme:(LITheme *)theme prefs:(FWPreferences *)prefs application:(FWApplication *)app
{
    PIEvent* event = (PIEvent*)item;
    BOOL showDetail = [self shouldShowDetailLine:event application:app preferences:prefs forItem:YES];
    BOOL hasHeader = event.sectionTitle && (event.sectionTitle.length > 0);  
    NSInteger indent = event.isInvitation ? 2 * kFWListViewBorderInset : 0;
    
    CGFloat summaryHeight = [PIEventView heightOfSummaryRowWithFont:theme.summaryStyle.font
                                                       withHeader:hasHeader
                                                 withFollowingRow:showDetail];
    
    if (showDetail) {
        CGFloat detailHeight = [PIEventView heightOfDetailRowWithFont:theme.detailStyle.font];
        return summaryHeight + detailHeight + indent;
    }
    else
        return summaryHeight + indent;
}


// ******************************************************************************************
#pragma mark -
#pragma mark Providing data for the display

- (FWListView*)viewForTheme:(LITheme*)theme existing:(UIView*)existing prefs:(FWPreferences*)prefs application:(FWApplication*)app
{
    if ([existing isKindOfClass:[PIEventView class]])
        return (PIEventView*)existing;
    else
        return [[[PIEventView alloc] initWithFrame:CGRectMake(0, 0, 320, 0)
                                             theme:theme
                                       application:app] autorelease];
}

- (void)setDetailsUsingView:(FWListView *)view forItem:(NSObject *)item theme:(LITheme *)theme prefs:(FWPreferences *)prefs application:(FWApplication *)app
{
    PIEventStatus* info = (PIEventStatus*)app.info;
    
    if (item) {
        // Don't display on the lockscreen
        ShowDatesOptions showDates = (ShowDatesOptions)info.showListDetails;
        if (app.isLockScreen && ![FWPreferences boolValue:kPIOptionsLockDetails withDefault:kPIOptionsLockDetailsDefault preferences:app.fwPlugin.liPlugin.preferences])
            showDates = ShowDatesNever;

        [(PIEventView*)view setViewForEvent:(PIEvent*)item
                                      theme:theme application:app
                                      style:info.viewStyle
                                 showDetail:showDates
                               showCalendar:info.isShowCalendar
                                   showDate:NO
                           showAvailability:info.isShowAvailability
                                  lowColour:info.isLowColour
                                 sourceIcon:(ShowSourceIconOptions)info.showSourceIcons
                                 emojiAfter:info.emojiAfter];
    }
    else {
        PIEventPlugin* cal = (PIEventPlugin*)app.fwPlugin;
        view.summaryText.text = [NSString stringWithFormat:@"⚡ %@    🔔 %@",
                                 FWDebugTimeStringForUTCDate(info.nextChangeDue),
                                 FWDebugTimeStringForUTCDate(info.nextAlarmDue)];
        view.detailText.text = [NSString stringWithFormat:@"🌙 %@    ⚠ %@",
                                FWDebugTimeStringForUTCDate(cal.muteUntilDate),
                                FWDebugTimeStringForUTCDate(app.fwPlugin.nextScheduledActivity)];
    }
    
    //    // Do we want everything on one line for an iPad?
    //    view.singleLine = FWIsDeviceAnIPad() && info.isSingleLineOniPad;
    //    if (view.singleLine) {
    //        ((PIEventView*)view).combineHighlight = NO;
    //    }
}

- (NSString*)detailForHeader:(FWPreferences*)prefs application:(FWApplication*)app
{
    return nil;
}


// ******************************************************************************************
#pragma mark -
#pragma mark Implement preview display

- (UIView*)previewWithFrame:(CGRect)rect atIndex:(NSInteger)index forItems:(NSArray *)list theme:(LITheme *)theme prefs:(FWPreferences *)prefs application:(FWApplication *)app
{   
    PIEvent* event = [list objectAtIndex:index];
    if (event.isReminderInteract) {
        // Show menu as the event is set for interaction
        NSInteger toolbarIndex = index + 1;
        if (app.fwPlugin.toolbarIndex == toolbarIndex)
            [app.fwPlugin hideToolbar];
        else
            [app.fwPlugin setToolbarIndex:toolbarIndex];

        return nil;
    }
    
    LIPlugin* plugin = (LIPlugin*)[app.fwPlugin liPlugin];
    
    // Are previews disabled?
    if (![FWPreferences boolValue:kPIOptionsShowPreviews withDefault:kPIOptionsShowPreviewsDefault preferences:plugin.preferences])
        return nil;
    
    // Don't display on the lockscreen
    if (app.isLockScreen && ![FWPreferences boolValue:kPIOptionsLockPreview withDefault:kPIOptionsLockPreviewDefault preferences:plugin.preferences])
        return nil;
    
    return [self previewWithFrame:rect atIndex:index forItems:list application:app];
}

- (FWDetailListView*)previewWithFrame:(CGRect)rect atIndex:(NSInteger)index forItems:(NSArray*)list application:(FWApplication*)app
{   
    PIEventPreview* previewData = [[[PIEventPreview alloc] initWithApplication:app] autorelease];
    FWDetailListView *thePreview = [[[FWDetailListView alloc] initWithFrame:rect
                                                                       list:list
                                                                      index:index
                                                                    caption:@"ListView/Event %i/%i"
                                                                application:app
                                                                   delegate:previewData] autorelease];
    return thePreview;
}


- (void)scheduleExtraAlarmForId:(NSString*)key atDate:(NSDate*)date type:(kPIEventAlarmType)type
{
    XLog(@"LI:PIEvent: Adding extra alarm instance at %@", date);
    [additionalAlarms addObject:[PIAlarm alarmWithKey:key date:date type:type]];
}


// ******************************************************************************************
#pragma mark -
#pragma mark Libstatusbar support

- (NSString*)libstatusbarIconName
{
    return @"PICalPlugin";
}

- (BOOL)showLibstatusbarIconForItems:(NSArray*)items prefs:(FWPreferences *)prefs
{
    if ([prefs boolValue:kPIOptionsShowStatusbarIcons withDefault:kPIOptionsShowStatusbarIconsDefault]) {
        for (PIEvent* event in items) {
            // If we've reached another day then we don't want an icon
            if (!FWIsLocalDateToday(event.startDate))
                return NO;
            
            // If we have a timed event today then we want an icon
            if (!event.isAllDay)
                return YES;
        }
    }
    
    return NO;
}

@end
